package com.catsic.logs.aop;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ReflectionUtils;

import com.catsic.base.BaseInfo;
import com.catsic.base.annotation.Log;
import com.catsic.base.utils.BaseUtils;
import com.catsic.logs.service.LogsService;

@Aspect
public class LogsAspect {
	
	public static String SUCCESS = "成功"; 
	
	public static String FAILURE = "失败"; 
	
	@Autowired  
    private LogsService logsService;
        
    @AfterReturning(pointcut="@annotation(com.catsic.base.annotation.Log)", argNames="rtv", returning="rtv") 
    public void log(JoinPoint joinPoint, Object rtv) throws Exception {
    	addLog(joinPoint, SUCCESS);
    }
    
    @AfterThrowing(pointcut="@annotation(com.catsic.base.annotation.Log)", throwing="e") 
    public void log(JoinPoint joinPoint, Exception e) throws Exception { 
    	addLog(joinPoint, FAILURE);
    }
      
    /**
     * 添加日志
     * @param joinPoint
     * @throws Exception
     */
    public void addLog(JoinPoint joinPoint, String bool) throws Exception{
    	BaseInfo baseInfo = BaseUtils.loginUserId();  
        if(baseInfo == null){
            return;  
        }  
        
        String module = null;
          
        /*
         * 获取方法名  
         */
        //String methodName = joinPoint.getSignature().getName();
        String operation = null;
        Method method=((MethodSignature)joinPoint.getSignature()).getMethod();
        
        Method realMethod=joinPoint.getTarget().getClass().getMethod(method.getName(), method.getParameterTypes());
        if(realMethod.isAnnotationPresent(Log.class)){
        	Log log = (Log)realMethod.getAnnotation(Log.class);
        	module = log.module();
        	operation = log.operation();
        }
        /*
         * 获取操作内容 
         */
        //String opContent = userOptionContent(joinPoint.getArgs(), methodName);  
        
        /*
         * 记录日志
         */
        logsService.add(baseInfo,module,operation,bool);
    }
    
    /** 
     * 使用Java反射来获取被拦截方法的参数值， 
     * 将参数值拼接为操作内容 
     */  
    public String userOptionContent(Object[] args, String mName) throws Exception{  
  
        if (args == null) {  
            return null;  
        }  
          
        StringBuffer rs = new StringBuffer();  
        rs.append(mName);  
        String className = null;  
        int index = 1;  
        /**
         * 遍历参数对象  
         */
        for (Object info : args) { 
        	
            /**
             * 获取对象类型  
             */
            className = info.getClass().getSimpleName();
            rs.append("[参数" + index + "，类型：" + className + "，值：");  
            Field[] fields = {};           
            /**
             * 获取父类的所有方法  
             */
            @SuppressWarnings("rawtypes")
			Class superClass = info.getClass().getSuperclass();
            while(superClass != null){
            	fields = superClass.getDeclaredFields();
            	getFieldValue(info,fields,rs);
            	superClass = superClass.getSuperclass();
            }
            
            fields = info.getClass().getDeclaredFields();
            getFieldValue(info,fields,rs);
            
            rs.append("]");  
            index++;  
        }  
          
        return rs.toString();  
    }
    
    public StringBuffer getFieldValue(Object info, Field[] fields,StringBuffer rs) throws Exception{
    	for (Field field : fields) {
    		if(StringUtils.equals(field.getName(), "serialVersionUID")){
    			continue;
    		}
    		field.setAccessible(true);
    		Object value = ReflectionUtils.getField(field, info);
            if(value != null){
            	rs.append("(" + field.getName() + " : " + value + ")");  
            }
        }  
		return rs;
    }
    
    public String getPackage(Package packages){
    	while(!packages.isAnnotationPresent(Log.class)){
    		if(StringUtils.countMatches(packages.getName(), ".") > 2) {
    			String pkgs = StringUtils.substringBeforeLast(packages.getName(), ".");
    			packages = Package.getPackage(pkgs);
    			getPackage(packages);
    		}
    	}
    	String moduleName = null;
		if(packages.isAnnotationPresent(Log.class)){
    		/**
    		 * 若存在就获取注解
    		 */
            Log annotation=(Log)packages.getAnnotation(Log.class);
            /**
             * 获取注解属性
             */
            moduleName = annotation.value();
    	}
		return moduleName;
    }
}
